"""
数据安全保护服务

提供数据传输加密、敏感数据脱敏和数据访问审计，包括：
- 数据传输加密(TLS/HTTPS)
- 数据存储加密
- 敏感数据脱敏
- 数据访问审计
- 数据备份和恢复
- 数据完整性验证
"""
import os
import json
import hashlib
import secrets
import base64
import time
import re
from typing import Dict, List, Any, Optional, Union, Tuple
from datetime import datetime, timedelta
from dataclasses import dataclass, field
from enum import Enum
import logging

try:
    from cryptography.fernet import Fernet
    from cryptography.hazmat.primitives import hashes, serialization
    from cryptography.hazmat.primitives.asymmetric import rsa, padding
    from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
    CRYPTO_AVAILABLE = True
except ImportError:
    CRYPTO_AVAILABLE = False
    print("⚠️ cryptography库未安装，数据加密功能将受限")

# 配置日志
logging.basicConfig(level=logging.INFO)
security_logger = logging.getLogger('data_security')


class DataClassification(Enum):
    """数据分类枚举"""
    PUBLIC = "public"           # 公开数据
    INTERNAL = "internal"       # 内部数据
    CONFIDENTIAL = "confidential"  # 机密数据
    RESTRICTED = "restricted"   # 限制数据
   


class EncryptionType(Enum):
    """加密类型枚举"""
    NONE = "none"
    SYMMETRIC = "symmetric"     # 对称加密
    ASYMMETRIC = "asymmetric"   # 非对称加密
    HYBRID = "hybrid"           # 混合加密


class AuditAction(Enum):
    """审计动作枚举"""
    CREATE = "create"
    READ = "read"
    UPDATE = "update"
    DELETE = "delete"
    EXPORT = "export"
    IMPORT = "import"
    ENCRYPT = "encrypt"
    DECRYPT = "decrypt"


@dataclass
class DataItem:
    """数据项"""
    data_id: str
    name: str
    content: Union[str, bytes, Dict[str, Any]]
    classification: DataClassification
    encryption_type: EncryptionType = EncryptionType.NONE
    owner_id: str = ""
    created_at: datetime = field(default_factory=datetime.now)
    updated_at: datetime = field(default_factory=datetime.now)
    access_count: int = 0
    checksum: str = ""
    metadata: Dict[str, Any] = field(default_factory=dict)


@dataclass
class EncryptionKey:
    """加密密钥"""
    key_id: str
    key_type: str  # symmetric, public, private
    key_data: bytes
    created_at: datetime = field(default_factory=datetime.now)
    expires_at: Optional[datetime] = None
    is_active: bool = True
    usage_count: int = 0


@dataclass
class AuditRecord:
    """审计记录"""
    audit_id: str
    user_id: str
    data_id: str
    action: AuditAction
    timestamp: datetime = field(default_factory=datetime.now)
    ip_address: Optional[str] = None
    user_agent: Optional[str] = None
    success: bool = True
    details: Dict[str, Any] = field(default_factory=dict)
    risk_level: str = "low"  # low, medium, high, critical


@dataclass
class DataMaskingRule:
    """数据脱敏规则"""
    rule_id: str
    name: str
    pattern: str  # 正则表达式
    replacement: str  # 替换模式
    data_types: List[str] = field(default_factory=list)
    is_active: bool = True


class DataSecurityService:
    """数据安全保护服务"""
    
    def __init__(self, master_key: Optional[str] = None):
        self.master_key = master_key or self._generate_master_key()
        
        # 存储
        self.data_items: Dict[str, DataItem] = {}
        self.encryption_keys: Dict[str, EncryptionKey] = {}
        self.audit_records: List[AuditRecord] = []
        self.masking_rules: Dict[str, DataMaskingRule] = {}
        
        # 加密器
        if CRYPTO_AVAILABLE:
            self.fernet = Fernet(base64.urlsafe_b64encode(self.master_key[:32].encode().ljust(32)[:32]))
        else:
            self.fernet = None
        
        # 安全配置
        self.security_config = {
            'enable_encryption_at_rest': True,
            'enable_encryption_in_transit': True,
            'default_key_expiry_days': 365,
            'audit_retention_days': 90,
            'enable_data_masking': True,
            'require_checksum_verification': True,
            'max_access_attempts': 10,
            'enable_backup_encryption': True
        }
        
        # 初始化默认脱敏规则
        self._initialize_default_masking_rules()
    
    def _generate_master_key(self) -> str:
        """生成主密钥"""
        return secrets.token_urlsafe(32)
    
    def _initialize_default_masking_rules(self):
        """初始化默认脱敏规则"""
        default_rules = [
            {
                'rule_id': 'email_mask',
                'name': '邮箱脱敏',
                'pattern': r'([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})',
                'replacement': r'\1***@\2',
                'data_types': ['email', 'contact']
            },
            {
                'rule_id': 'phone_mask',
                'name': '电话脱敏',
                'pattern': r'(\d{3})\d{4}(\d{4})',
                'replacement': r'\1****\2',
                'data_types': ['phone', 'contact']
            },
            {
                'rule_id': 'id_card_mask',
                'name': '身份证脱敏',
                'pattern': r'(\d{6})\d{8}(\d{4})',
                'replacement': r'\1********\2',
                'data_types': ['id_card', 'identity']
            },
            {
                'rule_id': 'name_mask',
                'name': '姓名脱敏',
                'pattern': r'(?<![a-zA-Z\u4e00-\u9fa5])([\u4e00-\u9fa5]{1})([\u4e00-\u9fa5]{1,3})(?![a-zA-Z\u4e00-\u9fa5])',
                'replacement': r'\1*',
                'data_types': ['name', 'personal']
            }
        ]
        
        for rule_data in default_rules:
            rule = DataMaskingRule(**rule_data)
            self.masking_rules[rule.rule_id] = rule
    
    def encrypt_data(self, data: Union[str, bytes, Dict[str, Any]], 
                    classification: DataClassification,
                    encryption_type: EncryptionType = EncryptionType.SYMMETRIC,
                    user_id: str = "") -> Dict[str, Any]:
        """加密数据"""
        try:
            data_id = f"data_{int(time.time() * 1000)}_{secrets.token_hex(4)}"
            
            # 序列化数据
            if isinstance(data, dict):
                serialized_data = json.dumps(data, ensure_ascii=False)
            elif isinstance(data, str):
                serialized_data = data
            else:
                serialized_data = data.decode() if isinstance(data, bytes) else str(data)
            
            # 计算校验和
            checksum = hashlib.sha256(serialized_data.encode()).hexdigest()
            
            # 根据分类决定是否加密
            encrypted_content = serialized_data
            actual_encryption_type = EncryptionType.NONE
            
            if (classification in [DataClassification.CONFIDENTIAL, DataClassification.RESTRICTED] and 
                self.security_config['enable_encryption_at_rest'] and 
                CRYPTO_AVAILABLE):
                
                if encryption_type == EncryptionType.SYMMETRIC:
                    encrypted_content = self._encrypt_symmetric(serialized_data)
                    actual_encryption_type = EncryptionType.SYMMETRIC
                elif encryption_type == EncryptionType.ASYMMETRIC:
                    encrypted_content = self._encrypt_asymmetric(serialized_data)
                    actual_encryption_type = EncryptionType.ASYMMETRIC
                elif encryption_type == EncryptionType.HYBRID:
                    encrypted_content = self._encrypt_hybrid(serialized_data)
                    actual_encryption_type = EncryptionType.HYBRID
            
            # 创建数据项
            data_item = DataItem(
                data_id=data_id,
                name=f"data_{data_id}",
                content=encrypted_content,
                classification=classification,
                encryption_type=actual_encryption_type,
                owner_id=user_id,
                checksum=checksum
            )
            
            self.data_items[data_id] = data_item
            
            # 调试信息
            security_logger.info(f"数据项创建: data_id={data_id}, owner_id={user_id}, classification={classification.value}")
            
            # 记录审计日志
            self._log_audit_record(
                user_id=user_id,
                data_id=data_id,
                action=AuditAction.ENCRYPT,
                details={
                    'classification': classification.value,
                    'encryption_type': actual_encryption_type.value,
                    'data_size': len(serialized_data)
                }
            )
            
            return {
                'success': True,
                'data_id': data_id,
                'encryption_type': actual_encryption_type.value,
                'checksum': checksum
            }
            
        except Exception as e:
            self._log_audit_record(
                user_id=user_id,
                data_id="",
                action=AuditAction.ENCRYPT,
                success=False,
                details={'error': str(e)},
                risk_level="high"
            )
            return {'success': False, 'error': f'数据加密失败: {str(e)}'}
    
    def decrypt_data(self, data_id: str, user_id: str = "") -> Dict[str, Any]:
        """解密数据"""
        try:
            if data_id not in self.data_items:
                return {'success': False, 'error': '数据不存在'}
            
            data_item = self.data_items[data_id]
            
            # 检查访问权限
            # 如果数据有明确的所有者，只有所有者可以访问
            if data_item.owner_id and data_item.owner_id != user_id:
                self._log_audit_record(
                    user_id=user_id,
                    data_id=data_id,
                    action=AuditAction.READ,
                    success=False,
                    details={'reason': 'access_denied', 'owner_id': data_item.owner_id, 'requester_id': user_id},
                    risk_level="medium"
                )
                return {'success': False, 'error': '访问权限不足'}
            
            # 解密数据
            decrypted_content = data_item.content
            
            if data_item.encryption_type == EncryptionType.SYMMETRIC:
                decrypted_content = self._decrypt_symmetric(data_item.content)
            elif data_item.encryption_type == EncryptionType.ASYMMETRIC:
                decrypted_content = self._decrypt_asymmetric(data_item.content)
            elif data_item.encryption_type == EncryptionType.HYBRID:
                decrypted_content = self._decrypt_hybrid(data_item.content)
            
            # 验证校验和
            if self.security_config['require_checksum_verification']:
                current_checksum = hashlib.sha256(decrypted_content.encode()).hexdigest()
                if current_checksum != data_item.checksum:
                    self._log_audit_record(
                        user_id=user_id,
                        data_id=data_id,
                        action=AuditAction.READ,
                        success=False,
                        details={'reason': 'checksum_mismatch'},
                        risk_level="critical"
                    )
                    return {'success': False, 'error': '数据完整性验证失败'}
            
            # 更新访问记录
            data_item.access_count += 1
            data_item.updated_at = datetime.now()
            
            # 记录审计日志
            self._log_audit_record(
                user_id=user_id,
                data_id=data_id,
                action=AuditAction.DECRYPT,
                details={
                    'classification': data_item.classification.value,
                    'encryption_type': data_item.encryption_type.value,
                    'access_count': data_item.access_count
                }
            )
            
            # 尝试反序列化JSON数据
            try:
                parsed_data = json.loads(decrypted_content)
                return {
                    'success': True,
                    'data': parsed_data,
                    'classification': data_item.classification.value,
                    'metadata': data_item.metadata
                }
            except json.JSONDecodeError:
                return {
                    'success': True,
                    'data': decrypted_content,
                    'classification': data_item.classification.value,
                    'metadata': data_item.metadata
                }
            
        except Exception as e:
            self._log_audit_record(
                user_id=user_id,
                data_id=data_id,
                action=AuditAction.DECRYPT,
                success=False,
                details={'error': str(e)},
                risk_level="high"
            )
            return {'success': False, 'error': f'数据解密失败: {str(e)}'}
    
    def mask_sensitive_data(self, data: Union[str, Dict[str, Any]], 
                          data_types: Optional[List[str]] = None) -> Dict[str, Any]:
        """脱敏敏感数据"""
        try:
            if not self.security_config['enable_data_masking']:
                return {'success': True, 'masked_data': data}
            
            masked_data = data
            applied_rules = []
            
            if isinstance(data, str):
                masked_data = self._apply_masking_rules(data, data_types)
                applied_rules = self._get_applicable_rules(data_types)
            elif isinstance(data, dict):
                masked_data = {}
                for key, value in data.items():
                    if isinstance(value, str):
                        masked_data[key] = self._apply_masking_rules(value, data_types)
                    else:
                        masked_data[key] = value
                applied_rules = self._get_applicable_rules(data_types)
            
            return {
                'success': True,
                'masked_data': masked_data,
                'applied_rules': [rule.rule_id for rule in applied_rules]
            }
            
        except Exception as e:
            return {'success': False, 'error': f'数据脱敏失败: {str(e)}'}
    
    def create_backup(self, data_ids: List[str], user_id: str = "") -> Dict[str, Any]:
        """创建数据备份"""
        try:
            backup_id = f"backup_{int(time.time() * 1000)}_{secrets.token_hex(4)}"
            backup_data = {}
            
            for data_id in data_ids:
                if data_id in self.data_items:
                    data_item = self.data_items[data_id]
                    backup_data[data_id] = {
                        'name': data_item.name,
                        'content': data_item.content,
                        'classification': data_item.classification.value,
                        'encryption_type': data_item.encryption_type.value,
                        'checksum': data_item.checksum,
                        'metadata': data_item.metadata,
                        'created_at': data_item.created_at.isoformat(),
                        'updated_at': data_item.updated_at.isoformat()
                    }
            
            # 序列化备份数据
            backup_json = json.dumps(backup_data, ensure_ascii=False)
            
            # 加密备份（如果启用）
            if self.security_config['enable_backup_encryption'] and CRYPTO_AVAILABLE:
                encrypted_backup = self._encrypt_symmetric(backup_json)
            else:
                encrypted_backup = backup_json
            
            # 保存备份（这里简化为内存存储）
            backup_file = f"backup_{backup_id}.json"
            
            # 记录审计日志
            self._log_audit_record(
                user_id=user_id,
                data_id=",".join(data_ids),
                action=AuditAction.EXPORT,
                details={
                    'backup_id': backup_id,
                    'data_count': len(data_ids),
                    'backup_size': len(backup_json),
                    'encrypted': self.security_config['enable_backup_encryption']
                }
            )
            
            return {
                'success': True,
                'backup_id': backup_id,
                'backup_file': backup_file,
                'data_count': len(data_ids),
                'encrypted': self.security_config['enable_backup_encryption']
            }
            
        except Exception as e:
            return {'success': False, 'error': f'备份创建失败: {str(e)}'}
    
    def verify_data_integrity(self, data_id: str) -> Dict[str, Any]:
        """验证数据完整性"""
        try:
            if data_id not in self.data_items:
                return {'success': False, 'error': '数据不存在'}
            
            data_item = self.data_items[data_id]
            
            # 解密数据以验证完整性
            decrypted_content = data_item.content
            
            if data_item.encryption_type == EncryptionType.SYMMETRIC:
                decrypted_content = self._decrypt_symmetric(data_item.content)
            elif data_item.encryption_type == EncryptionType.ASYMMETRIC:
                decrypted_content = self._decrypt_asymmetric(data_item.content)
            elif data_item.encryption_type == EncryptionType.HYBRID:
                decrypted_content = self._decrypt_hybrid(data_item.content)
            
            # 计算当前校验和
            current_checksum = hashlib.sha256(decrypted_content.encode()).hexdigest()
            
            # 比较校验和
            integrity_valid = current_checksum == data_item.checksum
            
            return {
                'success': True,
                'data_id': data_id,
                'integrity_valid': integrity_valid,
                'original_checksum': data_item.checksum,
                'current_checksum': current_checksum,
                'last_updated': data_item.updated_at.isoformat()
            }
            
        except Exception as e:
            return {'success': False, 'error': f'完整性验证失败: {str(e)}'}
    
    def _encrypt_symmetric(self, data: str) -> str:
        """对称加密"""
        if not CRYPTO_AVAILABLE or not self.fernet:
            return data
        
        encrypted_data = self.fernet.encrypt(data.encode())
        return base64.b64encode(encrypted_data).decode()
    
    def _decrypt_symmetric(self, encrypted_data: str) -> str:
        """对称解密"""
        if not CRYPTO_AVAILABLE or not self.fernet:
            return encrypted_data
        
        try:
            decoded_data = base64.b64decode(encrypted_data.encode())
            decrypted_data = self.fernet.decrypt(decoded_data)
            return decrypted_data.decode()
        except Exception:
            return encrypted_data
    
    def _encrypt_asymmetric(self, data: str) -> str:
        """非对称加密"""
        if not CRYPTO_AVAILABLE:
            return data
        
        try:
            # 生成RSA密钥对
            private_key = rsa.generate_private_key(
                public_exponent=65537,
                key_size=2048
            )
            public_key = private_key.public_key()
            
            # 加密数据
            encrypted_data = public_key.encrypt(
                data.encode(),
                padding.OAEP(
                    mgf=padding.MGF1(algorithm=hashes.SHA256()),
                    algorithm=hashes.SHA256(),
                    label=None
                )
            )
            
            # 保存私钥用于解密
            private_pem = private_key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.PKCS8,
                encryption_algorithm=serialization.NoEncryption()
            )
            
            key_id = f"rsa_{int(time.time() * 1000)}_{secrets.token_hex(4)}"
            self.encryption_keys[key_id] = EncryptionKey(
                key_id=key_id,
                key_type="private",
                key_data=private_pem
            )
            
            # 返回加密数据和密钥ID
            result = {
                'encrypted_data': base64.b64encode(encrypted_data).decode(),
                'key_id': key_id
            }
            
            return json.dumps(result)
            
        except Exception:
            return data
    
    def _decrypt_asymmetric(self, encrypted_data: str) -> str:
        """非对称解密"""
        if not CRYPTO_AVAILABLE:
            return encrypted_data
        
        try:
            data_dict = json.loads(encrypted_data)
            encrypted_bytes = base64.b64decode(data_dict['encrypted_data'])
            key_id = data_dict['key_id']
            
            if key_id not in self.encryption_keys:
                return encrypted_data
            
            # 加载私钥
            private_key = serialization.load_pem_private_key(
                self.encryption_keys[key_id].key_data,
                password=None
            )
            
            # 解密数据
            decrypted_data = private_key.decrypt(
                encrypted_bytes,
                padding.OAEP(
                    mgf=padding.MGF1(algorithm=hashes.SHA256()),
                    algorithm=hashes.SHA256(),
                    label=None
                )
            )
            
            return decrypted_data.decode()
            
        except Exception:
            return encrypted_data
    
    def _encrypt_hybrid(self, data: str) -> str:
        """混合加密（对称+非对称）"""
        if not CRYPTO_AVAILABLE:
            return data
        
        try:
            # 生成随机对称密钥
            symmetric_key = Fernet.generate_key()
            fernet = Fernet(symmetric_key)
            
            # 用对称密钥加密数据
            encrypted_data = fernet.encrypt(data.encode())
            
            # 生成RSA密钥对
            private_key = rsa.generate_private_key(
                public_exponent=65537,
                key_size=2048
            )
            public_key = private_key.public_key()
            
            # 用公钥加密对称密钥
            encrypted_symmetric_key = public_key.encrypt(
                symmetric_key,
                padding.OAEP(
                    mgf=padding.MGF1(algorithm=hashes.SHA256()),
                    algorithm=hashes.SHA256(),
                    label=None
                )
            )
            
            # 保存私钥
            private_pem = private_key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.PKCS8,
                encryption_algorithm=serialization.NoEncryption()
            )
            
            key_id = f"hybrid_{int(time.time() * 1000)}_{secrets.token_hex(4)}"
            self.encryption_keys[key_id] = EncryptionKey(
                key_id=key_id,
                key_type="private",
                key_data=private_pem
            )
            
            # 返回加密结果
            result = {
                'encrypted_data': base64.b64encode(encrypted_data).decode(),
                'encrypted_key': base64.b64encode(encrypted_symmetric_key).decode(),
                'key_id': key_id
            }
            
            return json.dumps(result)
            
        except Exception:
            return data
    
    def _decrypt_hybrid(self, encrypted_data: str) -> str:
        """混合解密"""
        if not CRYPTO_AVAILABLE:
            return encrypted_data
        
        try:
            data_dict = json.loads(encrypted_data)
            encrypted_data_bytes = base64.b64decode(data_dict['encrypted_data'])
            encrypted_key_bytes = base64.b64decode(data_dict['encrypted_key'])
            key_id = data_dict['key_id']
            
            if key_id not in self.encryption_keys:
                return encrypted_data
            
            # 加载私钥
            private_key = serialization.load_pem_private_key(
                self.encryption_keys[key_id].key_data,
                password=None
            )
            
            # 解密对称密钥
            symmetric_key = private_key.decrypt(
                encrypted_key_bytes,
                padding.OAEP(
                    mgf=padding.MGF1(algorithm=hashes.SHA256()),
                    algorithm=hashes.SHA256(),
                    label=None
                )
            )
            
            # 用对称密钥解密数据
            fernet = Fernet(symmetric_key)
            decrypted_data = fernet.decrypt(encrypted_data_bytes)
            
            return decrypted_data.decode()
            
        except Exception:
            return encrypted_data
    
    def _apply_masking_rules(self, text: str, data_types: Optional[List[str]] = None) -> str:
        """应用脱敏规则"""
        masked_text = text
        
        for rule in self.masking_rules.values():
            if not rule.is_active:
                continue
            
            # 检查数据类型匹配
            if data_types and rule.data_types:
                if not any(dt in rule.data_types for dt in data_types):
                    continue
            
            try:
                masked_text = re.sub(rule.pattern, rule.replacement, masked_text)
            except Exception as e:
                security_logger.warning(f"脱敏规则应用失败: {rule.rule_id} - {str(e)}")
        
        return masked_text
    
    def _get_applicable_rules(self, data_types: Optional[List[str]] = None) -> List[DataMaskingRule]:
        """获取适用的脱敏规则"""
        applicable_rules = []
        
        for rule in self.masking_rules.values():
            if not rule.is_active:
                continue
            
            if data_types and rule.data_types:
                if any(dt in rule.data_types for dt in data_types):
                    applicable_rules.append(rule)
            elif not data_types:
                applicable_rules.append(rule)
        
        return applicable_rules
    
    def _log_audit_record(self, user_id: str, data_id: str, action: AuditAction,
                         ip_address: Optional[str] = None, user_agent: Optional[str] = None,
                         success: bool = True, details: Optional[Dict[str, Any]] = None,
                         risk_level: str = "low"):
        """记录审计日志"""
        audit_record = AuditRecord(
            audit_id=f"audit_{int(time.time() * 1000)}_{secrets.token_hex(4)}",
            user_id=user_id,
            data_id=data_id,
            action=action,
            ip_address=ip_address,
            user_agent=user_agent,
            success=success,
            details=details or {},
            risk_level=risk_level
        )
        
        self.audit_records.append(audit_record)
        
        # 记录到日志
        security_logger.info(
            f"Data Security Audit: {action.value} - User: {user_id} - Data: {data_id} - "
            f"Success: {success} - Risk: {risk_level} - Details: {details}"
        )
        
        # 限制审计记录大小
        if len(self.audit_records) > 50000:
            self.audit_records = self.audit_records[-25000:]
    
    def get_audit_records(self, user_id: Optional[str] = None, 
                         data_id: Optional[str] = None,
                         action: Optional[AuditAction] = None,
                         start_date: Optional[datetime] = None,
                         end_date: Optional[datetime] = None,
                         limit: int = 100) -> List[Dict[str, Any]]:
        """获取审计记录"""
        records = self.audit_records
        
        # 应用过滤条件
        if user_id:
            records = [r for r in records if r.user_id == user_id]
        
        if data_id:
            records = [r for r in records if r.data_id == data_id]
        
        if action:
            records = [r for r in records if r.action == action]
        
        if start_date:
            records = [r for r in records if r.timestamp >= start_date]
        
        if end_date:
            records = [r for r in records if r.timestamp <= end_date]
        
        # 按时间倒序排列
        records = sorted(records, key=lambda x: x.timestamp, reverse=True)
        
        # 限制数量
        records = records[:limit]
        
        # 转换为字典格式
        return [
            {
                'audit_id': r.audit_id,
                'user_id': r.user_id,
                'data_id': r.data_id,
                'action': r.action.value,
                'timestamp': r.timestamp.isoformat(),
                'ip_address': r.ip_address,
                'user_agent': r.user_agent,
                'success': r.success,
                'details': r.details,
                'risk_level': r.risk_level
            }
            for r in records
        ]
    
    def add_masking_rule(self, name: str, pattern: str, replacement: str,
                        data_types: Optional[List[str]] = None) -> Dict[str, Any]:
        """添加脱敏规则"""
        try:
            rule_id = f"rule_{int(time.time() * 1000)}_{secrets.token_hex(4)}"
            
            # 验证正则表达式
            re.compile(pattern)
            
            rule = DataMaskingRule(
                rule_id=rule_id,
                name=name,
                pattern=pattern,
                replacement=replacement,
                data_types=data_types or []
            )
            
            self.masking_rules[rule_id] = rule
            
            return {
                'success': True,
                'rule_id': rule_id,
                'message': '脱敏规则添加成功'
            }
            
        except re.error as e:
            return {'success': False, 'error': f'正则表达式无效: {str(e)}'}
        except Exception as e:
            return {'success': False, 'error': f'添加脱敏规则失败: {str(e)}'}
    
    def get_security_statistics(self) -> Dict[str, Any]:
        """获取安全统计信息"""
        total_data_items = len(self.data_items)
        encrypted_items = len([item for item in self.data_items.values() 
                              if item.encryption_type != EncryptionType.NONE])
        
        # 按分类统计
        classification_stats = {}
        for item in self.data_items.values():
            classification = item.classification.value
            classification_stats[classification] = classification_stats.get(classification, 0) + 1
        
        # 按加密类型统计
        encryption_stats = {}
        for item in self.data_items.values():
            encryption_type = item.encryption_type.value
            encryption_stats[encryption_type] = encryption_stats.get(encryption_type, 0) + 1
        
        # 审计统计
        total_audit_records = len(self.audit_records)
        recent_audits = [
            r for r in self.audit_records
            if (datetime.now() - r.timestamp).total_seconds() < 86400
        ]
        
        audit_action_stats = {}
        risk_level_stats = {}
        for record in recent_audits:
            action = record.action.value
            risk = record.risk_level
            audit_action_stats[action] = audit_action_stats.get(action, 0) + 1
            risk_level_stats[risk] = risk_level_stats.get(risk, 0) + 1
        
        return {
            'data_items': {
                'total': total_data_items,
                'encrypted': encrypted_items,
                'encryption_rate': encrypted_items / total_data_items if total_data_items > 0 else 0,
                'by_classification': classification_stats,
                'by_encryption_type': encryption_stats
            },
            'encryption_keys': {
                'total': len(self.encryption_keys),
                'active': len([k for k in self.encryption_keys.values() if k.is_active])
            },
            'masking_rules': {
                'total': len(self.masking_rules),
                'active': len([r for r in self.masking_rules.values() if r.is_active])
            },
            'audit_records': {
                'total': total_audit_records,
                'recent_24h': len(recent_audits),
                'by_action': audit_action_stats,
                'by_risk_level': risk_level_stats
            },
            'security_config': self.security_config
        }
    
    def cleanup_expired_keys(self) -> Dict[str, Any]:
        """清理过期密钥"""
        try:
            current_time = datetime.now()
            expired_keys = []
            
            for key_id, key in self.encryption_keys.items():
                if key.expires_at and current_time > key.expires_at:
                    key.is_active = False
                    expired_keys.append(key_id)
            
            return {
                'success': True,
                'expired_keys_count': len(expired_keys),
                'expired_keys': expired_keys
            }
            
        except Exception as e:
            return {'success': False, 'error': f'清理过期密钥失败: {str(e)}'}
    
    def cleanup_old_audit_records(self) -> Dict[str, Any]:
        """清理旧审计记录"""
        try:
            retention_days = self.security_config['audit_retention_days']
            cutoff_date = datetime.now() - timedelta(days=retention_days)
            
            original_count = len(self.audit_records)
            self.audit_records = [
                record for record in self.audit_records
                if record.timestamp > cutoff_date
            ]
            
            cleaned_count = original_count - len(self.audit_records)
            
            return {
                'success': True,
                'cleaned_records_count': cleaned_count,
                'remaining_records_count': len(self.audit_records)
            }
            
        except Exception as e:
            return {'success': False, 'error': f'清理审计记录失败: {str(e)}'}


# 示例使用
if __name__ == "__main__":
    # 创建数据安全服务实例
    security_service = DataSecurityService()
    
    # 测试数据加密
    test_data = {
        "name": "张三",
        "email": "zhangsan@example.com",
        "phone": "13812345678",
        "research_data": "这是一些重要的研究数据"
    }
    
    print("=== 数据安全保护服务测试 ===")
    
    # 加密数据
    encrypt_result = security_service.encrypt_data(
        data=test_data,
        classification=DataClassification.CONFIDENTIAL,
        encryption_type=EncryptionType.SYMMETRIC,
        user_id="user_001"
    )
    print(f"加密结果: {encrypt_result}")
    
    if encrypt_result['success']:
        data_id = encrypt_result['data_id']
        
        # 解密数据
        decrypt_result = security_service.decrypt_data(data_id, "user_001")
        print(f"解密结果: {decrypt_result}")
        
        # 数据脱敏
        mask_result = security_service.mask_sensitive_data(
            test_data, 
            data_types=['personal', 'contact']
        )
        print(f"脱敏结果: {mask_result}")
        
        # 验证数据完整性
        integrity_result = security_service.verify_data_integrity(data_id)
        print(f"完整性验证: {integrity_result}")
        
        # 创建备份
        backup_result = security_service.create_backup([data_id], "user_001")
        print(f"备份结果: {backup_result}")
    
    # 获取安全统计
    stats = security_service.get_security_statistics()
    print(f"安全统计: {json.dumps(stats, indent=2, ensure_ascii=False)}")
    
    # 获取审计记录
    audit_records = security_service.get_audit_records(limit=5)
    print(f"审计记录: {json.dumps(audit_records, indent=2, ensure_ascii=False)}")